package com.cskaoyan.service;

import com.cskaoyan.anno.RedisCache;
import com.cskaoyan.bean.*;
import com.cskaoyan.bean.role.bo.CreateRoleBo;
import com.cskaoyan.bean.role.bo.DeleteRoleBo;
import com.cskaoyan.bean.role.bo.UpdateRolePermissionBo;
import com.cskaoyan.bean.role.vo.CreateRoleVo;
import com.cskaoyan.bean.role.vo.RoleData;
import com.cskaoyan.bean.role.bo.RoleReq;
import com.cskaoyan.mapper.PermissionMapper;
import com.cskaoyan.mapper.RoleMapper;
import com.cskaoyan.mapper.SystemPermissionMapper;
import com.cskaoyan.util.CskaoyanPageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private AdminService adminService;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private SystemPermissionMapper systemPermissionMapper;

    @Autowired
    private RedisService redisService;

    @Override//暂时查询全部，看需求改更通用的
    public List<Role> getRoles() {
        RoleExample example = new RoleExample();
        List<Role> roles = roleMapper.selectByExample(example);
        return roles;
    }

    @Override
    public RoleData getRoleList(BaseReq req) {
        CskaoyanPageHelper.startPage(req);
        RoleReq roleReq = (RoleReq) req;
        String name = roleReq.getName();

        RoleExample example = new RoleExample();
        example.setOrderByClause( roleReq.getSort() + " " + roleReq.getOrder());
        RoleExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);//未被删除
        if (StringUtils.hasText(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        List<Role> roles = roleMapper.selectByExample(example);
        PageInfo<Role> rolePageInfo = new PageInfo<>(roles);
        long total = rolePageInfo.getTotal();
        RoleData roleData = new RoleData();
        roleData.setTotal(total);
        roleData.setItems(roles);

        return roleData;
    }

    /**
     * 创建角色
     * @param bo
     * @return
     */
    @Override
    public CreateRoleVo createRole(CreateRoleBo bo) {
        Role role = new Role();
        BeanUtils.copyProperties(bo, role);
        Date now = new Date();
        role.setAddTime(now);
        role.setUpdateTime(now);
        int update = roleMapper.insertSelective(role);
        if (update == 0) {
            return null;//插入失败
        }
        CreateRoleVo vo = new CreateRoleVo();
        BeanUtils.copyProperties(role, vo);//已包含id
        return vo;
    }
    //总是成功
    @Override//1 删除 role 2 删除admin表role数组里的值信息 3 逻辑删除permission表里的该role
    public boolean deleteRole(DeleteRoleBo bo) {
        if (bo == null || bo.getId() == null) return true;
        int id = bo.getId();
        //逻辑删除role
        Role role = new Role();
        role.setId(id);
        Date now = new Date();
        role.setUpdateTime(now);
        role.setDeleted(true);
        role.setUpdateTime(now);
        RoleExample example = new RoleExample();
        RoleExample.Criteria criteria = example.createCriteria();
        roleMapper.updateByPrimaryKeySelective(role);
        //真删除admin中的roleIds数组中的值
        adminService.deleteRoleFromAllAdmin(id);
        //逻辑删除permission表里的该role
        Permission permission = new Permission();
        permission.setDeleted(true);
        permission.setUpdateTime(now);
        PermissionExample permissionExample = new PermissionExample();
        PermissionExample.Criteria permissionCriteria = permissionExample.createCriteria();
        permissionCriteria.andRoleIdEqualTo(id);
        permissionMapper.updateByExampleSelective(permission, permissionExample);
        return true;
    }
    //return 0 ok 1 失败 ，但总是成功
    @Override
    public int updateRole(Role role) {
        role.setUpdateTime(new Date());
        RoleExample example = new RoleExample();
        int update = roleMapper.updateByPrimaryKeySelective(role);
        return 0;//不判断是因为，数据库编的数据有可能没有这个 role的id
    }

    /**
     * 获取角色对应的权限列表
   * @param roleId
     * @return
     */
    @Override
    public List<Permission> getRolePermissions(Integer roleId) {
        PermissionExample example = new PermissionExample();
        PermissionExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdEqualTo(roleId);
        criteria.andDeletedEqualTo(false);//逻辑存在的权限
        List<Permission> permissions = permissionMapper.selectByExample(example);
        return permissions;
    }

    /**1 从redis中取 没有 从数据库查 -> 放入redis 返回 ; 由切面控制
     * 递归查询所有系统权限配置信息
     * @return
     */
    @RedisCache
    @Override
    public List<SystemPermission> getSystemPermissions() {
        //递归 从0开始，0是八大基类
        List<SystemPermission> systemPermissions = getSystemPermissions(0);
        return systemPermissions;
    }


    //递归查询所有系统权限配置信息
    private List<SystemPermission> getSystemPermissions(Integer parentKey) {
        SystemPermissionExample example = new SystemPermissionExample();
        SystemPermissionExample.Criteria criteria = example.createCriteria();
        criteria.andParentKeyEqualTo(parentKey);
        List<SystemPermission> systemPermissions = systemPermissionMapper.selectByExample(example);

        if (systemPermissions == null || systemPermissions.size() == 0) {
            return null;
        }
        for (SystemPermission systemPermission : systemPermissions) {
            Integer key = systemPermission.getKey();
            List<SystemPermission> children = getSystemPermissions(key);
            systemPermission.setChildren(children);
        }
        return systemPermissions;
    }
    /**
     *递归填充数据库 数据贴在AdminRoleConotroller调用处
     * @param systemPermission
     * @return
     */
    @Override
    public boolean writeData(SystemPermission systemPermission) {
        recurseWriteData(systemPermission);
        return false;
    }

    //递归写入数据
    private void recurseWriteData(SystemPermission systemPermission) {
        systemPermissionMapper.insertSelective(systemPermission);
        List<SystemPermission> children = systemPermission.getChildren();
        if (children == null || children.size() == 0) {
            return;
        }
        //生成主键注入子类开始递归
        Integer key = systemPermission.getKey();
        for (SystemPermission child : children) {
            child.setParentKey(key);
            recurseWriteData(child);
        }
    }

    /**
     * 更新角色权限
     * @param bo
     * @return  TODO 超级权限 只添加 * 需要添加判断
     */         //总是成功
    @Override//1 全部失效 2 部分激活 3 如果没有就新增
    public int updateRolePermissions(UpdateRolePermissionBo bo) {
        int roleId = bo.getRoleId();
        List<String> permissions = bo.getPermissions();
        changeDeleteStatus(roleId, null, true);
        Date now = new Date();
        for (String permission : permissions) {
            int active = changeDeleteStatus(roleId, permission, false);
            if (active == 0) {//如果没有就增加一个
                Permission p = new Permission(null, roleId, permission, now, now, null);
                addRolePermission(p);
            }
        }
        return 0;
    }

    private void addRolePermission(Permission p) {
      permissionMapper.insertSelective(p);
    }

    //逻辑修改角色权限删除状态
    private int changeDeleteStatus(Integer roleId, String p, boolean status) {
        Permission permission = new Permission();
        permission.setDeleted(status);
        permission.setUpdateTime(new Date());
        PermissionExample example = new PermissionExample();
        PermissionExample.Criteria criteria = example.createCriteria();
        if (roleId != null) {
            criteria.andRoleIdEqualTo(roleId);
        }
        if (p != null) {
            criteria.andPermissionEqualTo(p);
        }
        return permissionMapper.updateByExampleSelective(permission, example);
    }
}
